home *** CD-ROM | disk | FTP | other *** search
- /*
- File: FBA.c
-
- Contains:
-
- Written by: Greg Sutton
-
- Copyright: Copyright © 1996-1999 by Apple Computer, Inc., All Rights Reserved.
-
- You may incorporate this Apple sample source code into your program(s) without
- restriction. This Apple sample source code has been provided "AS IS" and the
- responsibility for its operation is yours. You are not permitted to redistribute
- this Apple sample source code as "Apple sample source code" after having made
- changes. If you're going to re-distribute the source, we require that you make
- it clear in the source that the code was descended from Apple sample source
- code, but that you've made changes.
-
- Change History (most recent first):
- 7/21/1999 Karl Groethe Updated for Metrowerks Codewarror Pro 2.1
-
-
- */
-
- // Includes
- #include "FBA.h"
- #include "FBAAppleEvents.h"
- #include "FBATask.h"
- #include "FBALists.h"
-
- #include <Gestalt.h>
- #include <LowMem.h>
- #include <Events.h>
- #include <Notification.h>
- #include <Resources.h>
-
- #ifdef DEVELOPMENT
- #include <TextEdit.h>
- #include <Dialogs.h>
- #endif
-
-
- // Prototypes
- static void IncreaseFBAStack(Size extraBytes);
- static Boolean HasFullExtFSDispatching( void );
- static Boolean HasProcessManager( void );
- static void InitCycleTime( void );
- static unsigned long GetResourceCycleTime( void );
-
- static void CheckEventQueue( void );
-
- static void Notify( StringPtr notice, Boolean fFatal );
-
- static pascal void MyResponse( NMRecPtr n );
-
-
- // Globals
- #if !defined(THINK_C) && !defined(__MWERKS__)
- QDGlobals qd;
- #endif
-
- short gQuit = false;
- unsigned long gCycleTime; // Time requested to check all folders
-
- // Constants
- const unsigned long DefaultCycleTime = 30; // Default cycle time for all folders
- // to be checked in seconds.
- const short StackSize = 32; // Default stack size for an FBA is 2K
- // Set StackSize to the K wanted.
-
-
- void main( void )
- {
- Boolean fQuit;
-
- IncreaseFBAStack(StackSize * 1024);
-
- MaxApplZone();
-
- InitGraf( &qd.thePort ); // Always call InitGraf; otherwise,
- // AppleEvents, Random(), and other calls won't work.
-
- #ifdef DEVELOPMENT // See 'FBA.h' for #define
- InitFonts( );
- InitWindows( );
- InitMenus( );
- TEInit( );
- InitDialogs( 0L );
- InitCursor( );
- #endif
-
- if ( noErr != InitAppleEvents( ) )
- Notify( "\pFolder Watcher failed to initialize Apple events", kFatalErr );
-
- if ( ! HasFullExtFSDispatching( ) )
- Notify( "\pFolder Watcher failed due to limited CatSearch", kFatalErr );
-
- if ( ! HasProcessManager( ) )
- Notify( "\pFolder Watcher failed due to no Process Manager", kFatalErr );
-
- if ( ! InitTask( ) )
- Notify( "\pFolder Watcher failed due to bad task initialization", kFatalErr );
-
- InitWatchFolders( );
- InitCycleTime( );
-
- fQuit = gQuit; // Initialization may set gQuit to true
-
- while ( ! fQuit )
- {
- CheckEventQueue( );
-
- if ( gQuit ) // We want to quit
- fQuit = CanQuitTask( ); // Check that our task can quit now
- }
- }
-
- // Increase the space allocated for the background only application
- // stack.
- //
- // Call this routine before calling MaxApplZone, during program
- // initialization.
- //
- // Warning:
- // SetApplLimit always sets the stack to at least as large as the
- // default stack for the machine (8K on machines with original
- // QuickDraw, 24K on machines with Color QuickDraw), so the
- // application partition must be large enough to accommodate an
- // appropriate stack and heap.
- //
- // Call this only once, at the beginning of the background only
- // application.
- //
- // Another warning:
- // Don't bother trying to set the stack size to something lower
- // than 24K. If SetApplLimit is called to do this, it will
- // silently lower ApplLimit to a 24K stack.
-
- static void IncreaseFBAStack(Size extraBytes)
- {
- THz myZone;
- SysEnvRec sys;
-
- SysEnvirons(1, &sys);
-
- if (sys.systemVersion < 0x0755)
- {
- // Check that we aren't running with a corrupt heap. If we are,
- // fix the problem. This was a bug with FBA's before System 7.5.5.
- myZone = GetZone();
- if (myZone->bkLim != LMGetHeapEnd())
- LMSetHeapEnd(myZone->bkLim);
- }
- // Increase the stack size by lowering the heap limit.
- SetApplLimit((Ptr) ((Size) GetApplLimit() - extraBytes));
- }
-
-
- static void CheckEventQueue( void )
- {
- long sleepTicks = 1; // First time through return from
- // WaitNextEvent() as quick as possible.
- EventRecord anEvent;
- OSErr err;
-
- WaitNextEvent( highLevelEventMask, &anEvent, sleepTicks, NULL );
-
- switch ( anEvent.what )
- {
- case kHighLevelEvent :
- err = DoAppleEvent( &anEvent );
- break;
- }
-
- // Call background task no matter if event
- // is a high level or null event.
- sleepTicks = DoBackgroundTask( ); // Do our background task or return
- // an updated sleep time.
- }
-
-
- // See if File Manager will pass CatSearch requests to external file systems.
-
- static Boolean HasFullExtFSDispatching( void )
- {
- long response;
- Boolean result = false;
-
- if ( noErr == Gestalt( gestaltFSAttr, &response ) )
- result = ((response & (1L << gestaltFullExtFSDispatching)) != 0);
-
- return result;
- }
-
-
- // Check that we have the process manager
-
- static Boolean HasProcessManager( void )
- {
- long response;
- Boolean result = false;
-
- if ( noErr == Gestalt( gestaltOSAttr, &response ) )
- result = true;
-
- return result;
- }
-
-
- static void InitCycleTime( void )
- {
- gCycleTime = GetResourceCycleTime();
- }
-
-
- unsigned long GetCycleTime( void )
- {
- return gCycleTime;
- }
-
-
- // If there are 'Cycl' resources then use the first of these for the sleep time.
- // Otherwise use the default cycle time. The time is supposed to be in seconds.
-
- static unsigned long GetResourceCycleTime( void )
- {
- short count;
- Handle aHandle;
- unsigned long result = DefaultCycleTime;
-
- count = Count1Resources( kCycleTimeResource );
- if ( count )
- {
- aHandle = Get1IndResource( kCycleTimeResource, 1 );
- if ( aHandle )
- {
- result = *(unsigned long *) *aHandle;
- ReleaseResource( aHandle );
- }
- }
-
- return result;
- }
-
-
-
- static pascal void MyResponse ( NMRecPtr n )
- {
- DisposePtr ( (Ptr) n->nmStr );
- NMRemove ( n );
- if ( ! n->nmRefCon ) // true if error was fatal
- DisposePtr ( (Ptr) n );
- else
- n->nmRefCon = 0L;
-
- return;
- }
-
-
- // Use the Notification manager to display a message.
- // Pass true to fFatal if the applcation is to quit afterwards.
-
- void Notify( StringPtr notice, Boolean fFatal )
- {
- // remember, no user interface to play with
- NMRecPtr notePtr;
- OSErr err;
-
- notePtr = (NMRecPtr) NewPtr ( sizeof ( NMRec ) );
- if ( MemError ( ) )
- return;
-
- notePtr->qType = nmType; // standard queue type for NM
- notePtr->nmMark = 0; // background only
- notePtr->nmIcon = 0L;
- notePtr->nmSound = (Handle) -1L; // use system alert snd
- notePtr->nmStr = NULL;
- notePtr->nmStr = (StringPtr) NewPtr ( sizeof ( Str255 ) );
- BlockMoveData( notice, notePtr->nmStr, notice[0] + 1 );
- notePtr->nmResp = NewNMProc( MyResponse );
- notePtr->nmRefCon = fFatal;
-
- err = NMInstall ( notePtr );
- if ( err == noErr && fFatal )
- {
- while ( notePtr->nmRefCon )
- CheckEventQueue( );
- gQuit = true;
- }
-
- return;
- }
-